
在 JavaScript 中,变量提升(hoisting)和函数提升(hoisting)是两种相关但有所不同的机制。它们都与作用域和代码执行顺序有关,但具体行为有所区别。 变量提升(Hoisting for Variables) 变量提升是指变量声明会被提升到其作用域的顶部,但变量赋值不会提升。这意味着在代码执行之前,变量声明会被“移动”到当前作用域的最顶端,但赋值操作会留在原来的位置。 javascript复制代码console.log(a); // 输出: undefinedvar a = 2; 在上面的代码中,尽管 var a = 2; 出现在 console.log(a); 之后,但由于变量提升,var a; 声明被提升到了作用域顶部,但赋值 a = 2; 仍然留在原位置。因此,当执行到 console.log(a); 时,变量 a 已经声明但尚未赋值,所以输出 undefined。 函数提升(Hoisting for Functions) 函数提升是指函数声明会被完整地提升到其作用域的顶部,包括函数声明和函数体。这意味着在代码执行之前,整个函数声明会被“移动”到当前作用域的最顶端。 javascript复制代码console.log(foo()); // 输出: "Hello, world!"function foo() { return "Hello, world!";} 在上面的代码中,尽管 function foo() {...} 出现在 console.log(foo()); 之后,但由于函数提升,整个函数声明被提升到了作用域顶部。因此,当执行到 console.log(foo()); 时,函数 foo 已经完全可用,并返回 "Hello, world!"。 区别总结
提升内容不同:
变量提升只提升变量声明,不提升变量赋值。 函数提升提升整个函数声明,包括函数名和函数体。
输出不同:
变量提升后,在变量声明之前访问变量会返回 undefined。 函数提升后,在函数声明之前调用函数会正常执行并返回结果。
作用域和块级作用域:
变量提升适用于所有变量声明(var、let、const),但 let 和 const 声明具有块级作用域,并且不会真正“提升”到块作用域顶部(它们会保持“暂时性死区”直到声明位置),这与 var 的函数作用域不同。 函数提升只适用于函数声明(function),不适用于函数表达式(如 const foo = function() {...} 或 let foo = function() {...})。
通过理解这些区别,可以更好地编写和理解 JavaScript 代码的行为。